package com.benshou.bcss.common.j17common;

import lombok.NonNull;

import java.util.Comparator;
import java.util.function.Function;

/**
 * @author <a href="mailto:wh1zper@qq.com">wh1zper</a>
 */
public class ComparatorBuilder<T> {

    @NonNull
    private final Comparator<? super T> comparator;

    private Boolean nullLast;

    private Boolean reversed;

    public ComparatorBuilder(@NonNull Comparator<? super T> comparator) {
        this.comparator = comparator;
    }

    public <U extends Comparable<U>> ComparatorBuilder(
            @NonNull Function<? super T, ? extends U> mapper,
            @NonNull Comparator<? super U> comparator) {
        this(Comparator.comparing(mapper, comparator));
    }

    public <U extends Comparable<U>> ComparatorBuilder(@NonNull Function<? super T, ? extends U> mapper) {
        this(Comparator.comparing(mapper));
    }

    public static <TC extends Comparable<? super TC>> ComparatorBuilder<TC> naturalOrder() {
        return new ComparatorBuilder<>(Comparator.naturalOrder());
    }

    public ComparatorBuilder<T> reverse() {
        this.reversed = this.reversed == null || !this.reversed;
        return this;
    }

    public ComparatorBuilder<T> nullLast() {
        this.nullLast = true;
        return this;
    }

    public ComparatorBuilder<T> nullFirst() {
        this.nullLast = false;
        return this;
    }

    public Comparator<T> build() {
        @SuppressWarnings("unchecked")
        var comparator = (Comparator<T>) this.comparator;

        if (Boolean.TRUE.equals(this.reversed)) {
            comparator = comparator.reversed();
        }

        if (this.nullLast != null) {
            comparator = this.nullLast ? Comparator.nullsLast(comparator) : Comparator.nullsFirst(comparator);
        }

        return comparator;
    }
}
